//======================================================================================
//  Apache License, Version 2.0
//  Notes:Use this command to anonymously check out the latest project source code:
//  Non-members may check out a read-only working copy anonymously over HTTP.
//  SVN checkout http://YHHLineCommandWsp.googlecode.com/svn/trunk/ 
//
//  Author:		Kevin Yang
//  Email:		Bigearrabbit@qq.com
//
//  DATE:		2013-4-9
//
//  File Name:	YHHLineCommandCatalogCreate.cpp
//
//  Notes:
//
//======================================================================================
//===============================================================================================
//
//  Abstract:
//  ---------
//
//  Batch program which generates a catalog for a new mechanical feature : Line Command.
//    
//  Illustrates:
//     o -1- Creating a path to the catalog.
//     o -2- Creating the catalog.
//     o -3- Adding a client identification to the catalog.
//     o -4- Creating the new Line Command startup in the catalog.
//     o -5- Adding attributes to this startup.
//     o -6- Saving the catalog.
//    
//===============================================================================================
//
//  Usage:
//  ------
//
//  Type:
//     o YHHLineCommandCatalogCreate <directory name>
//
//  Example under Windows NT : 
//     o YHHLineCommandCatalogCreate E:\MyWsp\YHHLineCommandFrm\CNext\resources\graphic
//
//  NB : to be found at run-time, catalog must be in a resources\graphic directory.
//
//===============================================================================================

// MechanicalModeler Framework 
#include "CATMfDefs.h"                  // needed to define type MfGeom3D

// ObjectModelerBase Framework
#include "CATSessionServices.h"         // needed to manage session
#include "LifeCycleObject.h"            // needed to remove the catalog from the session
#include "CATDocument.h"                // needed to retrieve and then save the document ( not L1 )
#include "CATDocumentServices.h"        // needed to save the catalog
#include "CATSession.h"

// ObjectSpecsModeler Framework
#include "CATCatalogFactoryServices.h"  // needed to create a catalog
#include "CATICatalog.h"                // needed to manage catalogs
#include "CATISpecObject.h"             // needed to manage features such as the Line Command startup
#include "CATISpecAttribute.h"          // needed to add attributes to the Line Command startup
#include "CATOsmSUFactory.h"            // needed to create the Line Command startup

// System Framework
#include "CATUnicodeString.h"           // needed to give the catalog name
#include "CATLib.h"                     // needed to create the path to the catalog file
#include "CATBoolean.h"

//local Framework
#include "YHHCatalogParameter.h"
//YHHCatiaBaseUtlFrm Framework
#include "YHHListV.h"
// Others
#include "iostream.h"               // needed for cout traces
#include "CATIContainer.h"
int main (int argc, char * argv[] )
{ 
    //===============================================================================================
    //
    // -1- Creating a path to the catalog.
    // 
    //  o  "main" first argument is directory path : to use your catalog, it should be
    //     located under resources\graphic directory.
    //  o  Catalog file name is set to YHHLineCommandCatalog.
    //
    //     CATMakePath of CATLib.h creates an os dependant path.
    //
    //===============================================================================================
    
    cout << "-1- Creating a path to the catalog." << endl << flush;
    
    if ( argc < 2)
    {
        cout << "    ERROR  : no directory path given." << endl;
        return 0;
    }
    
    const char *pDirName     = argv[1];
    const char *pFileName    = "YHHLineCommandFeature.CATfct";//argv[2];
    char       StorageName[200];
	//cout << "argv[0]:" <<argv[0]<< endl << flush;
	//cout << "argv[1]:" <<argv[1]<< endl << flush;
    
    CATMakePath( pDirName , pFileName , StorageName );
	cout << "Catalog whole path:" <<StorageName<< endl << flush;
    
    //===============================================================================================
    // Creating a session.
    //===============================================================================================
     
    cout << "    Creating a session." << endl << flush;
    
    char       *pSessionName = "CAA2_Sample_Session";
    CATSession *pSession     = NULL;
    
    HRESULT rc = Create_Session( pSessionName , pSession );
    
    if ( SUCCEEDED(rc) )
        cout << "    Session creation OK." << endl << flush;
    else
    {
        cout << "    ERROR in creating the session." << endl << flush;
        return 1;
    }
    
    
    //===============================================================================================
    //
    // -2- Creating the catalog.
    //
    //     The ".CATfct" suffix is automatically added by CreateCatalog.
    //
    //===============================================================================================
	CATUnicodeString ClientId = "YHHLineCommandID";
   

    CATUnicodeString LineCommandCatalogStorageName = StorageName;
    CATICatalog      *piLineCommandCatalog          = NULL;

	//try to open first

	//===============================================================================================
	//
	// -1- Retrieves a CATIContainer interface pointer on this (CATPrtCont)
	//
	//===============================================================================================

	CATIContainer *piContainerOnThis = NULL;
	//HRESULT rc = CATBaseUnknown::QueryInterface( IID_CATIContainer , ( void**) &piContainerOnThis );
	//if ( FAILED(rc) )
	//{
	//	return rc;
	//}
	//===============================================================================================
	//
	// -2- Opens the Line Command catalog
	//
	//===============================================================================================

	CATUnicodeString StorageName1 = StorageName;
	rc = ::UpgradeCatalog( &LineCommandCatalogStorageName , &piLineCommandCatalog, &ClientId);
	if ( SUCCEEDED(rc))
	{
		cout << "-2- The catalog exist. Opened OK." << endl << flush;
	}
	else
	{
		cout << "-2- Catalog not exist ,Creating the catalog." << endl << flush;
		rc = ::CreateCatalog( &LineCommandCatalogStorageName , &piLineCommandCatalog );

		if ( SUCCEEDED(rc) ) 
			cout << "    Line Command Catalog created OK." << endl << flush;
		else    
		{ 
			cout << "    ERROR in creating Line Command Catalog." << endl << flush; 
			return 1; 
		}

		//===============================================================================================
		//
		// -3- Adding a client identification to the catalog.
		//
		//     This is a mandatory step.
		//
		//===============================================================================================

		cout << "-3- Adding a client identification to the catalog." << endl << flush;


		rc = piLineCommandCatalog->SetClientId( &ClientId );

		if ( SUCCEEDED(rc) ) 
			cout << "    Client Id set OK." << endl << flush;
		else    
		{ 
			cout << "    ERROR in setting Client Id." << endl << flush; 
			return 1; 
		}
	}

  
	//===============================================================================================
	//
	// -3- Retrieves Line Command's startup
	//
	//===============================================================================================

	CATBaseUnknown *pLineCommandStartup = NULL;
	CATUnicodeString StartupType = "YHHLineCommandChild";
	CATISpecObject *piSpecOnLineCommandStartUp = NULL;

	rc = piLineCommandCatalog->RetrieveSU( &pLineCommandStartup , &StartupType , "CATISpecObject" );
	if ( SUCCEEDED(rc) )  
	{

		rc = pLineCommandStartup->QueryInterface( IID_CATISpecObject , ( void**) &piSpecOnLineCommandStartUp );
		pLineCommandStartup->Release();
		pLineCommandStartup = NULL ;

	}
	//check 
	if (NULL == piSpecOnLineCommandStartUp)
	{

		//===============================================================================================
		//
		// -4- Creating the new Line Command startup in the catalog.
		//
		//     A Line Command is a kind of MfGeom3D, its StartUp derives from MfGeom3D's Startup.
		//     The generic factory is used to create a new Line Command
		//     StartUp deriving from MfGeom3D.
		//
		//===============================================================================================


		cout << "-4- Creating the new Line Command startup in the catalog." << endl << flush;

		CATUnicodeString LineCommandStartUpType = "YHHLineCommandChild";   
		CATUnicodeString CatalogName = "MechMod" ;
		CATUnicodeString SuperTypeName = "GeometricalElement3D";
		CATBoolean       publicSU = FALSE ;
		CATBoolean       derivableSU = FALSE ;

		rc = ::CATOsmSUFactory(&piSpecOnLineCommandStartUp,
			&LineCommandStartUpType,
			piLineCommandCatalog,
			&SuperTypeName,
			&CatalogName,
			publicSU,
			derivableSU) ; 

		if ( SUCCEEDED(rc) ) 
			cout << "    YHHLineCommandChild StartUp created using CATOsmSUFactory Factory OK." << endl << flush;
		else
		{
			cout << "    ERROR in creating YHHLineCommandChild StartUp using CATOsmSUFactory." << endl << flush; 
			return 1;
		}
	}
    
   
    //===============================================================================================
    //
    //  -5- Adding attributes to this startup.
    //===============================================================================================
    
    cout << "-5- Adding attributes to this startup." << endl << flush;
    
	YHHCatalogParameter Newparam;//new param
	YHH::ListV<YHHCatalogParameter> ListParam;//list of param

	//DO NOT EDIT IN THE CONTROL CODE OF "KEVIN CAA WIZARD SECTION"
	//START KEVIN CAA WIZARD SECTION YHHLineCommandChild CATALOG PARAMS
	//0;	ErrMsg;Kevin Yang;2013-4-5;	
	Newparam.SetValue("ErrMsg" , tk_string, sp_OUT);		ListParam.Append(Newparam);
	//1;	Start Point;Kevin Yang;2013-4-2;	
	Newparam.SetValue("StartPoint" , tk_specobject, sp_IN);		ListParam.Append(Newparam);
	//2;	Line Direction;Kevin Yang;2013-4-2;	
	Newparam.SetValue("LineDirection" , tk_specobject, sp_IN);		ListParam.Append(Newparam);
	//3;	Length Sign;Kevin Yang;2013-4-2;	
	Newparam.SetValue("LengthSign" , tk_integer, sp_IN);		ListParam.Append(Newparam);
	//4;	Length Start;Kevin Yang;2013-4-2;	
	Newparam.SetValue("LengthStart" , tk_double, sp_IN);		ListParam.Append(Newparam);
	//5;	Length End;Kevin Yang;2013-4-2;	
	Newparam.SetValue("LengthEnd" , tk_double, sp_IN);		ListParam.Append(Newparam);
	//END KEVIN CAA WIZARD SECTION YHHLineCommandChild CATALOG PARAMS

    // Adding  attribute : 
	for (int i=0;i<ListParam.size();i++)
	{
		YHHCatalogParameter & curParam = ListParam.at(i);//new param

		//chek name exist:


		//if not exist
		CATISpecAttribute *piCurve1SpecAttribute = piSpecOnLineCommandStartUp->
			AddAttribute(curParam.AttrName,curParam.AttrType,curParam.AttrInOut);

		if ( piCurve1SpecAttribute != NULL ) 
			cout << curParam.AttrName<<" attribute added OK." << endl << flush;
		else 
		{
			cout << "    ERROR in adding "<<curParam.AttrName<<" attribute." << endl << flush;
			return 1 ;
		}
		piCurve1SpecAttribute->Release();
		piCurve1SpecAttribute = NULL ;
	}
  
    // Releasing no longer used pointer on CATISpecObject.
    //----------------------------------------------------
    
    piSpecOnLineCommandStartUp -> Release();
    piSpecOnLineCommandStartUp  = NULL ;
       
    
    //===============================================================================================
    //
    // -6- Saving the catalog.
    //
    //===============================================================================================
    
    cout << "-6- Saving the catalog." << endl << flush;

    rc = ::SaveCatalog(&piLineCommandCatalog, &LineCommandCatalogStorageName);

    if ( FAILED(rc) )
    {
        cout << "    ERROR in saving Line Command Catalog." << endl << flush;
        return 1;
    }

    piLineCommandCatalog -> Release();
    piLineCommandCatalog = NULL;
   
    // Deleting session
    //------------------
    
    rc = Delete_Session( pSessionName );

    if (FAILED(rc))
    {
        cout << "    ERROR in deleting session." << endl << flush;
        return 1;
    }
    return 0;
}
//---------------------------------------------------------
